package com.springboot.demo.controller;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.springboot.demo.common.customValidator.ListNotHasNull;
import com.springboot.demo.entity.*;
import com.springboot.demo.entity.validate.TableBasicInfoGroup;
import com.springboot.demo.entity.validate.user.IdGroup;
import com.springboot.demo.service.TableService;
import com.springboot.demo.utils.DateUtils;
import com.springboot.demo.utils.ResponseUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.validation.groups.Default;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author wubc683
 * @desc
 * @date 2021-11-18 14:14
 */
@RestController
@Api(tags = "报表接口")
@Validated
public class TableController {
    @Autowired
    ResponseUtils responseUtils;
    @Autowired
    TableService tableService;

    @GetMapping("/table/all")
    @ApiOperation(value = "获取所有报表")
    @ApiOperationSupport(order = 10)
    public ResponseUtils<List<Table>> getAllTables(
            @RequestParam(value = "search", required = false) @Length(max = 32, message = "搜索字段长度不超过32字符")
            @ApiParam(value = "1~32位", required = false) String search,
            @RequestParam(value = "type", required = false)
            @ApiParam(value = "报表类型,1:指标卡，2：列表，3：折线图，4：柱状图，5：堆叠柱状图，6：条形图，7：饼图") Integer type,
            @ApiParam(value = "排序字段(最多1个）,字段名+空格+排序方向,示例：升序[id asc]，降序[id desc]")
            @RequestParam(value = "sort", required = false) String sort,
            @RequestParam(value = "startDate", required = false) @ApiParam("起始日期")
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startDate,
            @RequestParam(value = "endDate", required = false) @ApiParam("结束日期")
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endDate,
            @Valid PageRequest pageRequest) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult allTables = tableService.getAllTables(implUser.getId(), search, type, sort, startDate, endDate, pageRequest);
        return responseUtils.buildSuccessResponse(allTables);
    }

    @GetMapping("/table/{tid}")
    @ApiOperation(value = "获取报表信息")
    @ApiOperationSupport(order = 40)
    public ResponseUtils<Table> getTable(@PathVariable("tid") Long tid) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        Table table = tableService.getTable(implUser.getId(), tid);
        return responseUtils.buildSuccessResponse(table);
    }

    @GetMapping("/table/types")
    @ApiOperation(value = "获取报表所有类型及其需要的字段")
    @ApiOperationSupport(order = 42)
    public ResponseUtils<List<TableType>> getTableTypes() {
        List<TableType> tableTypes = tableService.getTableTypes();
        return responseUtils.buildSuccessResponse(tableTypes);
    }

    @GetMapping("/table/dataTable")
    @ApiOperation(value = "获取数据表及其字段信息，维度，对比，值可选值为数据表对应的字段值")
    @ApiOperationSupport(order = 44)
    public ResponseUtils<List<TableDataTable>> getTableDataTables() {
        List<TableDataTable> tableDataTables = tableService.getTableDataTables();
        return responseUtils.buildSuccessResponse(tableDataTables);
    }

    @PostMapping("/table")
    @ApiOperation(value = "创建报表")
    @ApiOperationSupport(order = 50, includeParameters = {"table.title", "table.type", "table.dataTableType", "table" +
            ".dimension", "table.compare", "table.value", "table.valueType", "table.isExportAllowed", "table.filters" +
            ".filterField", "table.filters" +
            ".filterField", "table.filters.filterMode", "table.filters.filterDataType", "table.filters.filterData"})
    public ResponseUtils saveTable(@Validated({TableBasicInfoGroup.class, Default.class}) @RequestBody Table table) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        tableService.saveTable(implUser.getId(), table);
        return responseUtils.buildSuccessResponse();
    }

    @PutMapping("/table")
    @ApiOperation(value = "修改报表")
    @ApiOperationSupport(order = 60, includeParameters = {"table.id", "table.title", "table.type", "table" +
            ".dataTableType", "table" +
            ".dimension", "table.compare", "table.value", "table.valueType", "table.filters.filterField", "table.filters" +
            ".filterField", "table.filters.filterMode", "table.filters.filterDataType", "table.filters.filterData"})
    public ResponseUtils updateTable(@Validated({IdGroup.class, TableBasicInfoGroup.class, Default.class}) @RequestBody Table table) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        tableService.updateTable(implUser.getId(), table);
        return responseUtils.buildSuccessResponse();
    }

    @PostMapping("/table/del")
    @ApiOperation(value = "删除报表")
    @ApiOperationSupport(order = 70)
    public ResponseUtils deleteTable(@RequestBody @ListNotHasNull @Size(min = 1) List<Long> tableIds) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        tableService.deleteTable(implUser.getId(), tableIds);
        return responseUtils.buildSuccessResponse();
    }

    @GetMapping("/table/{tid}/data")
    @ApiOperation(value = "获取已保存报表数据", notes = "预览功能,返回值说明,1.指标卡，除了历史报警表和历史数据表中的变量值，值变量2个返回float型，其余均" +
            "返回long类型，2.饼图，")
    @ApiOperationSupport(order = 80)
    public ResponseUtils getTableResult(@PathVariable("tid") Long tid,
                                        @RequestParam(value = "sort", required = false) @ApiParam(
                                                value = "仅用于报表列表类型排序,格式：column+列序号+空格+asc或者desc" +
                                                        "，例如：\"column0" + " " + "asc\"," +
                                                        "\"column1 desc\"",
                                                required = false) String sort,
                                        @Valid PageRequest request) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult tableData = tableService.getTableData(implUser.getId(), tid, sort, request);
        return responseUtils.buildSuccessResponse(tableData);
    }

    @PostMapping("/table/data")
    @ApiOperation(value = "获取未保存的报表数据", notes = "即返回报表实际数据,用于报表制作中实时刷新查看,返回值说明同【获取已保存报表数据】接口")
    @ApiOperationSupport(order = 90, includeParameters = {"table.title", "table.type", "table.dataTableType", "table" +
            ".dimension", "table.compare", "table.value", "table.valueType", "table.filters.filterField", "table.filters" +
            ".filterField", "table.filters.filterMode", "table.filters.filterDataType", "table.filters.filterData",
            "sort", "pageNum", "pageSize"})
    public ResponseUtils getTableUnSavedResult(@Validated({TableBasicInfoGroup.class, Default.class}) @RequestBody Table table,
                                               @RequestParam(value = "sort", required = false) @ApiParam(
                                                       value = "仅用于报表列表类型排序,格式：column+列序号+空格+asc或者desc" +
                                                               "，例如：\"column0" + " " + "asc\"," +
                                                               "\"column1 desc\"",
                                                       required = false) String sort,
                                               @Valid PageRequest request) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        PageResult unSavedTableData = tableService.getUnSavedTableData(implUser.getId(), table, sort, request);
        return responseUtils.buildSuccessResponse(unSavedTableData);
    }

    @GetMapping("/table/dt/{dt}/fd/{fd}")
    @ApiOperation(value = "获取过滤字段数据")
    @ApiOperationSupport(order = 100)
    public ResponseUtils<List<String>> getTableFieldData(
            @PathVariable("dt") @ApiParam(name = "dt", value = "数据表序号1~5，见下面参数描述", required = true) Integer dataTableNum,
            @PathVariable(value = "fd") @ApiParam(name = "fd", value = "过滤字段序号,有效字段：1.用户表：用户名，手机号，角色名，" +
                    "2.设备表：设备名称，设备群组，省，市，区,3.场景表：场景名称，场景群组，设备名称，4.历史数据表：变量名称，设备名称，场景名称，" +
                    "5.历史报警表：触发变量，报警内容，设备名称，场景名称，其中：用户表的【电话是否校验】，0未校验，1已校验，设备表的【设备状态】，" +
                    "0离线，1在线，mac地址给出默认格式：【0F-0F-0F-0F-0F-0F】，场景表的【场景状态】，0未发布，1已发布，2在运行，3有设备离线，4有设备报警" +
                    "历史报警表中的【报警类型】，0模拟量，1离散量",
                    required = true) Integer fieldNum,
            @RequestParam(value = "search", required = false) @ApiParam(name = "search", value = "搜索内容,1~32")
            @Length(min = 1, max = 32) String search) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        UserDetailsImpl userDetailsImpl = (UserDetailsImpl) principal;
        User implUser = userDetailsImpl.getUser();
        List<String> tableFieldData = tableService.getTableFieldData(implUser.getId(), dataTableNum, fieldNum, search);
        return responseUtils.buildSuccessResponse(tableFieldData);
    }
}
